// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   GaugePlotter.java

package com.java4less.rchart;

import com.java4less.rchart.gc.ChartColor;
import com.java4less.rchart.gc.ChartGraphics;
import com.java4less.rchart.gc.GraphicsProvider;
import com.java4less.rchart.gc.Point;
import com.java4less.rchart.gc.Polygon;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Vector;

// Referenced classes of package com.java4less.rchart:
//			Plotter, LineStyle, FillStyle, GaugeDataSerie, 
//			DataSerie, Axis, Scale, Chart

public class GaugePlotter extends Plotter
{

	public int needleBase;
	public double radiusModifier;
	public LineStyle border;
	private Vector lblPositions;
	public int axis1LabelMargin;
	public int axis2LabelMargin;
	public int axis2Margin;
	public int axis1Margin;
	public Axis axis1;
	public Axis axis2;
	public FillStyle maxZoneColor;
	public int maxminZoneWidth;
	public int maxminZoneMargin;
	public double maxZone;
	public FillStyle minZoneColor;
	public double minZone;
	public int startAngle;
	public int endAngle;
	public FillStyle gaugeback;
	private int angleRange;
	private int CenterX;
	private int CenterY;
	public GaugePlotter subGauge1;
	public GaugePlotter subGauge2;
	protected GaugePlotter parentGauge;
	public int subGaugeSize;

	public GaugePlotter()
	{
		needleBase = 8;
		radiusModifier = 1.0D;
		border = new LineStyle(2.0F, GraphicsProvider.getColor(ChartColor.BLACK), 1);
		lblPositions = new Vector(10);
		axis1LabelMargin = 10;
		axis2LabelMargin = -20;
		axis2Margin = 40;
		axis1Margin = 5;
		maxZoneColor = new FillStyle(GraphicsProvider.getColor(ChartColor.RED));
		maxminZoneWidth = 50;
		maxminZoneMargin = 5;
		maxZone = -1D;
		minZoneColor = new FillStyle(GraphicsProvider.getColor(ChartColor.GREEN));
		minZone = -1D;
		startAngle = -20;
		endAngle = 200;
		gaugeback = new FillStyle(GraphicsProvider.getColor(ChartColor.BLUE));
		angleRange = 0;
		CenterX = 0;
		CenterY = 0;
		subGauge1 = null;
		subGauge2 = null;
		parentGauge = null;
		subGaugeSize = 30;
		combinable = false;
		needsAxis = 0;
	}

	protected void plotSerie(ChartGraphics g, DataSerie s, int serieSec)
	{
		int radi = 0;
		radi = width;
		if (height < radi)
			radi = height;
		radi = (int)((double)radi * radiusModifier);
		if (axis1 == null)
		{
			g.setColor(GraphicsProvider.getColor(ChartColor.RED));
			g.drawString("Error: No axis/scale has been defined", 30, 30);
			return;
		} else
		{
			int toCenterX = (width - radi) / 2;
			int toCenterY = (height - radi) / 2;
			s.hotAreas.removeAllElements();
			plotGauge(g, s, serieSec, toCenterX, toCenterY, radi, false);
			return;
		}
	}

	protected void plotGauge(ChartGraphics g, DataSerie s, int serieSec, int toCenterX, int toCenterY, int radi, boolean isSubGauge)
	{
		boolean circle = false;
		if (startAngle > 180 || endAngle > 180)
			circle = true;
		GaugeDataSerie p;
		if (s instanceof GaugeDataSerie)
			p = (GaugeDataSerie)s;
		else
			return;
		int tmpEnd = 180;
		if (circle)
			tmpEnd = 360;
		if (!circle)
			toCenterY += radi / 4;
		CenterX = toCenterX + x + radi / 2;
		CenterY = toCenterY + y + radi / 2;
		angleRange = startAngle - endAngle;
		angleRange = Math.abs(angleRange);
		if (axis1 != null)
		{
			axis1.scale.screenMin = 0;
			axis1.scale.screenMax = 100;
			axis1.scale.screenMaxMargin = 100;
			axis1.scale.reverse = false;
		}
		if (axis2 != null)
		{
			axis2.scale.screenMin = 0;
			axis2.scale.screenMax = 100;
			axis2.scale.screenMaxMargin = 100;
			axis2.scale.reverse = false;
		}
		gaugeback.drawArc(g, toCenterX + x, toCenterY + y, radi, radi, 0, tmpEnd);
		if (maxZone > 0.0D && axis1 != null)
		{
			int angle1 = getAngleForValue(axis1, maxZone);
			int angle2 = getAngleForValue(axis1, axis1.scale.max);
			maxZoneColor.drawArc(g, toCenterX + x + maxminZoneMargin, toCenterY + y + maxminZoneMargin, radi - maxminZoneMargin * 2, radi - maxminZoneMargin * 2, angle1, angle2 - angle1);
			int aux = -5;
			if (startAngle > endAngle)
				aux = 5;
			gaugeback.drawArc(g, toCenterX + x + (maxminZoneWidth + maxminZoneMargin), toCenterY + y + (maxminZoneWidth + maxminZoneMargin), radi - (maxminZoneWidth + maxminZoneMargin) * 2, radi - (maxminZoneWidth + maxminZoneMargin) * 2, angle1 + aux, angle2 - angle1 - aux * 2);
		}
		if (minZone > 0.0D && axis1 != null)
		{
			int angle2 = getAngleForValue(axis1, minZone);
			int angle1 = getAngleForValue(axis1, axis1.scale.min);
			minZoneColor.drawArc(g, toCenterX + x + maxminZoneMargin, toCenterY + y + maxminZoneMargin, radi - maxminZoneMargin * 2, radi - maxminZoneMargin * 2, angle1, angle2 - angle1);
			int aux = -5;
			if (startAngle > endAngle)
				aux = 5;
			gaugeback.drawArc(g, toCenterX + x + (maxminZoneWidth + maxminZoneMargin), toCenterY + y + (maxminZoneWidth + maxminZoneMargin), radi - (maxminZoneWidth + maxminZoneMargin) * 2, radi - (maxminZoneWidth + maxminZoneMargin) * 2, angle1 + aux, angle2 - angle1 - aux * 2);
		}
		if (axis2 != null)
			paintScale(g, axis2, axis2Margin, radi, axis2LabelMargin);
		if (axis1 != null)
			paintScale(g, axis1, axis1Margin, radi, axis1LabelMargin);
		if (border != null)
			border.drawArc(g, toCenterX + x, toCenterY + y, radi, radi, 0, tmpEnd);
		if (!circle)
			border.draw(g, toCenterX + x, toCenterY + y + radi / 2, toCenterX + x + radi, toCenterY + y + radi / 2);
		if (!isSubGauge && subGauge1 != null)
		{
			double subRadi = radi;
			subRadi = (subRadi * (double)subGaugeSize) / 100D;
			int subToCenterX = (int)((double)(toCenterX + radi / 2) - subRadi / 2D);
			int subToCenterY = (int)((double)(toCenterY + radi / 4) - subRadi / 2D);
			subGauge1.x = x;
			subGauge1.y = y;
			subGauge1.parentGauge = this;
			subGauge1.plotGauge(g, s, serieSec, subToCenterX, subToCenterY, (int)subRadi, true);
		}
		if (!isSubGauge && subGauge2 != null)
		{
			double subRadi = radi;
			subRadi = (subRadi * (double)subGaugeSize) / 100D;
			int subToCenterX = (int)((double)(toCenterX + radi / 2) - subRadi / 2D);
			int subToCenterY = (int)((double)(toCenterY + radi / 2 + radi / 4) - subRadi / 2D);
			subGauge2.x = x;
			subGauge2.y = y;
			subGauge2.parentGauge = this;
			subGauge2.plotGauge(g, s, serieSec, subToCenterX, subToCenterY, (int)subRadi, true);
		}
		int subGaugesCount = 0;
		int startPos = 0;
		if (!isSubGauge)
		{
			if (subGauge1 != null)
				subGaugesCount++;
			if (subGauge2 != null)
				subGaugesCount++;
		} else
		{
			startPos = p.yData.size() - 1;
			if (parentGauge.subGauge1 == this && parentGauge.subGauge2 != null)
				startPos = p.yData.size() - 2;
		}
		int count = p.yData.size() - subGaugesCount;
		int sCount = 0;
		for (int i = startPos; i < count; i++)
		{
			FillStyle tmpS = null;
			if (p.Styles.size() > i)
				tmpS = (FillStyle)p.Styles.elementAt(i);
			if (tmpS == null)
				tmpS = new FillStyle(p.needleStyle.color);
			LineStyle tmpL = new LineStyle(p.needleStyle.getWidth(), tmpS.color, p.needleStyle.getType());
			double tmp1 = (radi * needleBase) / 100;
			double tmp2 = ((radi / 2) * (100 - needleBase)) / 100;
			tmpS.drawArc(g, sCount * 3 + toCenterX + x + (int)tmp2, sCount * 3 + toCenterY + y + (int)tmp2, (int)tmp1 - sCount * 6, (int)tmp1 - sCount * 6, 0, 360);
			double YValue = ((Double)p.getElementY(i)).doubleValue();
			int angle = getAngleForValue(axis1, YValue);
			Point p1 = getArcPoint(angle, (int)(((double)(radi / 2) * (double)p.needleLength) / 100D));
			tmpL.draw(g, CenterX + p1.x, CenterY + p1.y, CenterX, CenterY);
			if (p.valueFont != null && i == startPos && !isSubGauge)
			{
				g.setFont(p.valueFont);
				g.setColor(p.valueColor);
				String txt = (new StringBuilder()).append("").append(YValue).toString();
				int FontH = g.getFontHeight();
				int FontW = g.getFontWidth(txt);
				g.drawString(txt, CenterX - FontW / 2, CenterY + FontH + 5 + (radi / 2) * (needleBase / 100));
			}
			if (isSubGauge)
				break;
			sCount++;
			if (isSubGauge)
				continue;
			Polygon po = new Polygon();
			po.addPoint(CenterX + p1.x, CenterY + p1.y);
			po.addPoint(CenterX, CenterY);
			if (p1.y <= 20)
			{
				po.addPoint(CenterX, CenterY + 5);
				po.addPoint(CenterX + p1.x, CenterY + p1.y + 5);
			} else
			{
				po.addPoint(CenterX + 5, CenterY);
				po.addPoint(CenterX + p1.x + 5, CenterY + p1.y);
			}
			s.hotAreas.addElement(po);
		}

	}

	private void paintScale(ChartGraphics g, Axis axis, int axisMargin, int radi, int axisLabelMargin)
	{
		int numberBigTicks = 0;
		int tickCount = 0;
		if (axis.startWithBigTick)
			tickCount = axis.bigTickInterval - 1;
		for (double v = axis.scale.min; v <= axis.scale.max; v += axis.scaleTickInterval)
		{
			tickCount++;
			int angle = getAngleForValue(axis, v);
			Point p1 = getArcPoint(angle, radi / 2 - axisMargin);
			int relativeY = p1.y;
			int relativeX = p1.x;
			p1 = getArcPoint(angle, radi / 2 - axis.tickPixels - axisMargin);
			int relativeY2 = p1.y;
			int relativeX2 = p1.x;
			if (tickCount == axis.bigTickInterval)
			{
				p1 = getArcPoint(angle, radi / 2 - axis.bigTickPixels - axisMargin);
				relativeY2 = p1.y;
				relativeX2 = p1.x;
			}
			axis.style.draw(g, CenterX + relativeX2, CenterY + relativeY2, CenterX + relativeX, CenterY + relativeY);
			if (tickCount != axis.bigTickInterval)
				continue;
			numberBigTicks++;
			if (axis.DescFont != null)
			{
				g.setFont(axis.DescFont);
				g.setColor(axis.DescColor);
				String txt = (new Double(v)).toString();
				if (axis.scaleLabelFormat.length() > 0)
				{
					DecimalFormat df = null;
					if (Chart.numberLocale == null)
					{
						df = new DecimalFormat(axis.scaleLabelFormat);
					} else
					{
						NumberFormat nf = NumberFormat.getNumberInstance(new Locale(Chart.numberLocale, ""));
						df = (DecimalFormat)nf;
						df.applyPattern(axis.scaleLabelFormat);
					}
					txt = df.format(new Double(v));
				}
				if (axis.IntegerScale)
					txt = (new Integer((int)v)).toString();
				if (axis.tickLabels != null)
					if (axis.tickLabels.length >= numberBigTicks)
						txt = axis.tickLabels[numberBigTicks - 1];
					else
						txt = " ";
				p1 = getArcPoint(angle, (radi / 2 - axisMargin) + axisLabelMargin);
				int h = g.getFontHeight();
				int w = g.getFontWidth(txt);
				Point p2 = getArcPoint(angle, radi / 2 - axisMargin);
				if (axis1LabelMargin > 0)
				{
					if (p1.x + w > p2.x && p1.x < p2.x)
						g.drawString(txt, (CenterX + p1.x) - w, CenterY + p1.y);
					else
						g.drawString(txt, CenterX + p1.x, CenterY + p1.y);
				} else
				if (p1.x + w > p2.x && p1.x < p2.x)
					g.drawString(txt, (CenterX + p1.x) - w, CenterY + p1.y);
				else
					g.drawString(txt, CenterX + p1.x, CenterY + p1.y);
			}
			tickCount = 0;
		}

	}

	private int getAngleForValue(Axis axis, double v)
	{
		int angle = (int)(((double)axis.scale.getScreenCoord(v) * (double)angleRange) / 100D);
		if (startAngle > endAngle)
		{
			angle = angleRange - angle;
			return endAngle + angle;
		} else
		{
			return startAngle + angle;
		}
	}

	private Point getArcPoint(int angle, int distanceCenter)
	{
		double radian = 0.017452777777777779D * (double)angle;
		double Sin = Math.sin(radian);
		double Cos = Math.cos(radian);
		double relativeY = Sin * (double)distanceCenter;
		double relativeX = Cos * (double)distanceCenter;
		relativeY *= -1D;
		return new Point((int)relativeX, (int)relativeY);
	}
}
